<?php
/**
 * Copyright (c) 2006-2008, Julien PORTALIER
 * http://featherphp.googlecode.com/
 * 
 * Originally derived from CakePHP,
 * Copyright (c) 2006, Cake Software Foundation, Inc.
 * 
 * Licensed under The MIT License
 * Redistributions of files must retain the above copyright notice.
 */

/**
 *  Manipulates HTML elements.
 */
class html
{
	/**
	 * 
	 * @return string
	 * @param $doctype String
	 */
	static function doctype($doctype)
	{
		switch($doctype)
		{
			// XHTML 1.1
			case "xhtml11":         return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.1//EN" "http://www.w3.org/TR/xhtml11/DTD/xhtml11.dtd">';
			
			// XHTML 1.0
			case "xhtml1-strict":   return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Strict//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-strict.dtd">';
			case "xhtml1-trans":    return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd">';
			case "xhtml1-frameset": return '<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Frameset//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-frameset.dtd">';
			
			// HTML 4.01
			case "html4-strict":    return '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">';
			case "html4-trans":     return '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd">';
			case 'html4-frameset':  return '<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Frameset//EN" "http://www.w3.org/TR/html4/frameset.dtd">';
			
			default:
				trigger_error("Unknown doctype: ".$doctype, E_USER_ERROR);
		}
	}
	
	/**
	 * 
	 * @return string
	 * @param $namespace String
	 * @param $lang String[optional]
	 */
	static function namespace($namespace, $lang=null)
	{
		if (empty($lang) and isset($GLOBALS['self']->Locale)) {
			$lang = $GLOBALS['self']->Locale->lang;
		}
		switch($namespace)
		{
			# XHTML
			case "xhtml11":
			case "xhtml1-strict":
			case "xhtml1-trans":
			case "xhtml1-frameset":
				return '<html xmlns="http://www.w3.org/1999/xhtml"'.(empty($lang) ? null : ' xml:lang="'.$lang.'"').'>';
			
			# HTML
			default:
				return '<html'.(empty($lang) ? null : ' lang="'.$lang.'"').'>';
		}
	}
	
	/**
	 * 
	 * @return string
	 * @param $name String
	 * @param $content String
	 */
	static function meta($name, $content)
	{
		return html::tag('meta', array('name' => $name, 'content' => $content));
	}
	
	/**
	 * 
	 * @return string
	 * @param $content_type String[optional]
	 * @param $charset String[optional]
	 */
	static function charset($content_type='text/html', $charset=null)
	{
		return html::tag('meta', array(
			'http-equiv' => 'Content-Type',
			'content'    => $content_type.'; charset='.(empty($charset) ? Core::charset : $charset)
		));
	}
	
	/**
	 * 
	 * @return string
	 * @param $url   String
	 * @param $media String[optional]
	 * @param $attr  Array[optional]
	 */
	static function css($url, $media=null, array $attr=null)
	{
		if (is_array($url))
		{
			$str = '';
			foreach($url as $_url) {
				$str = self::css($_url, $media, $attr);
			}
			return $str;
		}
		
		# href
		if (strpos($url, 'http://') !== 0
			and strpos($url, 'https://') !== 0)
		{
			if (substr($url, 0, 1) != '/') {
				$url = "/css/$url";
			}
			$sep = strpos($url, '?') ? '&amp;' : '?';
			$attr['href']  = $url.$sep.@filemtime(WWW_ROOT.$url);
		}
		else {
			$attr['href'] = $url;
		}
		
		# attributes
		if (!empty($media)) {
			$attr['media'] = $media;
		}
		$attr['rel']     = 'stylesheet';
		$attr['type']    = 'text/css';
		$attr['charset'] = strtolower(Core::charset);
		$attr['href']    = html::url($attr['href']);
		
		return html::tag('link', &$attr);
	}
	
	/**
	 * 
	 * @return string
	 * @param $url     String
	 * @param $content String[optional]
	 * @param $attr    Array[optional]
	 */
	static function js($url, array $attr=null)
	{
		if (is_array($url))
		{
			$str = '';
			foreach($url as $_url) {
				$str = self::js($_url, $attr);
			}
			return $str;
		}
		
		# src
		if (strpos($url, 'http://') !== 0
			and strpos($url, 'https://') !== 0)
		{
			if (substr($url, 0, 1) != '/') {
				$url = "/js/$url";
			}
			$sep = strpos($url, '?') ? '&amp;' : '?';
			$attr['src']  = $url.$sep.@filemtime(WWW_ROOT.$url);
		}
		else {
			$attr['src'] = $url;
		}
		
		# attributes
		$attr['type']    = 'text/javascript';
		$attr['charset'] = strtolower(Core::charset);
		$attr['src']     = html::url($attr['src']);
		
		return html::content_tag('script', '', &$attr);
	}
	
	/**
	 * 
	 * @return string
	 * @param $content Object
	 * @param $attr Object[optional]
	 */
	static function js_script($content, array $attr=null)
	{
		$attr['type']    = 'text/javascript';
		$attr['charset'] = strtolower(Core::charset);
		$content = "\n// <![CDATA[\n$content\n// ]]>\n";
		return html::content_tag('script', $content, &$attr);
	}
	
	/**
	 * 
	 * @return string
	 * @param $title String
	 * @param $url   String
	 * @param $rel   String[optional]
	 * @param $attr  Array[optional]
	 */
	static function rss($title, $url, $rel='alternate', $attr=null)
	{
		$attr['rel']   = $rel;
		$attr['type']  = 'application/rss+xml';
		$attr['title'] = $title;
		$attr['href']  = html::url($url);
		return html::tag('link', &$attr);
	}
	
	
	// TAGS
	
	/**
	 * 
	 * @return string
	 * @param $url String
	 */
	static function url($url)
	{
		# do not process URL?
		if (preg_match('/^(#|(http|ftp)s?:\/\/|(javascript|mailto):)/', $url)) {
			return $url;
		}
		
		# prefixes URL with controller's viewpath
		if (substr($url, 0, 1) != '/')
		{
			$self = $GLOBALS['self'];
#			$prefix = isset($self->Config, $self->Config->plugin, $self->Config->plugin->base_path) ?
#				$self->Config->plugin->base_path.'/' : '/';
			$prefix = (isset($self->Config) and $self->Config->is_set('plugin', 'base_url')) ?
				$self->Config->get('plugin', 'base_url') : '/';
			$url = "{$prefix}{$self->view_path}/$url";
		}
		
		# fixes unencoded ampersands
		return preg_replace('/&([^a])/', '&amp;\1', $url);
	}
	
	/**
	 * 
	 * @return string
	 * @param $url_or_title String
	 * @param $url          String[optional]
	 * @param $confirm      String[optional]
	 * @param $attr         Array[optional]
	 */
	static function link($url_or_title, $url=null, $confirm=null, array $attr=null)
	{
		if (!empty($confirm))
		{
			if (!is_array($confirm)) {
				$attr['onclick'] = 'javascript:return confirm(\''.htmlspecialchars($confirm).'\');';
			}
			else {
				$attr = $confirm;
			}
		}
		
		if (is_null($url)) {
			$url = $url_or_title;
		}
		$attr['href'] = html::url($url);
		
		return html::content_tag('a', $url_or_title, &$attr);
	}
	
	/**
	 * 
	 * @return string
	 * @param $url String
	 * @param $alt String[optional]
	 * @param $attr Array[optional]
	 */
	static function img($url, $alt='', array $attr=null)
	{
		if (strpos($url, 'http://') !== 0 and strpos($url, 'https://') !== 0)
		{
			$sep = strpos($url, '?') ? '&amp;' : '?';
			$attr['src'] = html::url($url).$sep.@filemtime(WWW_ROOT.$url);
		}
		else {
			$attr['src'] = $url;
		}
		$attr['alt'] = $alt;
		return html::tag('img', &$attr);
	}
	
	
	// GENERICS
	
	/**
	 * Changes relative paths for absolute ones in an HTML string.
	 * 
	 * @return string
	 * @param $html     String
	 * @param $base_url String
	 */
	function fix_relative_paths($html, $base_url)
	{
		return preg_replace(
			'{<([^<>]*)(href|src|data)="(?!(?:http[s]?|mailto|ftp[s]?):|#)([^>"]*)"}i',
			'<\1\2="'.$base_url.'\3"',
			$html
		);
	}
	
	/**
	 * 
	 * @return string
	 * @param $tag String
	 * @param $attr Array[optional]
	 */
	static function tag($tag, array $attr=null)
	{
		$attr = html::parse_attributes(&$attr);
		return "<$tag$attr />";
	}
	
	/**
	 * 
	 * @return string
	 * @param $tag String
	 * @param $attr Array[optional]
	 */
	static function start_tag($tag, array $attr=null)
	{
		$attr = html::parse_attributes(&$attr);
		return "<$tag$attr>";
	}
	
	/**
	 * 
	 * @return string
	 * @param $tag String
	 * @param $attr Array[optional]
	 */
	static function end_tag($tag)
	{
		return "</$tag>";
	}
	
	/**
	 * 
	 * @return string
	 * @param $tag     String
	 * @param $content String
	 * @param $attr    Array[optional]
	 */
	static function content_tag($tag, $content, array $attr=null)
	{
		$attr = html::parse_attributes(&$attr);
		return "<$tag$attr>$content</$tag>";
	}
	
	/**
	 * 
	 * @return string
	 * @param $attr Array
	 */
	static function parse_attributes(array $attr)
	{
		if (empty($attr))
			return;
		
		$str = '';
		foreach($attr as $k => $v)
		{
#			if ($k == 'value')
#				$v = htmlspecialchars($v);
			$str .= " $k=\"$v\"";
		}
		return $str;
	}
}
?>
